package com.mactivity.activities;

import android.app.Activity;
import android.app.AlertDialog;
import android.app.AlertDialog.Builder;
import android.app.Dialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.os.Bundle;
import android.os.StrictMode;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;

import com.mactivity.database.LoginFunctions;
import com.mactivity.database.RegistrationFunctions;
import com.mactivity.helper.Constants;
import com.mactivity.helper.EncryptionHelper;
import com.mactivity.helper.MailHelper;
import com.mactivity.helper.Messages;
import com.mactivity.helper.RandomPasswordHelper;
import com.mactivity.helper.ValidationsHelper;

/**
 * This class contains the UI interactions and the event handling that occur on
 * the UI.
 * 
 * @author Shwetha Narayan
 * 
 */
public class RegisterActivity extends Activity implements OnClickListener {
	// Screen variables
	EditText emailId;
	EditText fullName;
	Button buttonRegister;
	Button buttonCancel;

	String returnCount, returnString;

	// Dialogue variable
	private static final int INVALID_EMAIL = 11;
	private static final int FIELD_BLANK = 12;
	private static final int EMAIL_NOT_AVAILABLE = 13;
	private static final int NAME_INVALID = 15;
	private static final int UNKNOWN_ERROR = 14;
	private static final int SUCCESS_REG = 16;

	/**
	 * This method is called on the activity creation. It locates the screen
	 * elements and binds the elements to the functions that occur.
	 */
	@Override
	public void onCreate(Bundle savedInstanceState) {
		// TODO what is this Strict Mode
		StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder()
				.detectDiskReads().detectDiskWrites().detectNetwork()
				.penaltyLog().build());

		super.onCreate(savedInstanceState);
		setContentView(R.layout.registration_screen);

		// Find the value in the edit text
		emailId = (EditText) findViewById(R.id.editEmailId);
		fullName = (EditText) findViewById(R.id.editFullName);

		// Find the buttons on the screen
		buttonRegister = (Button) findViewById(R.id.buttonRegister);
		buttonCancel = (Button) findViewById(R.id.buttonCancel);

		// On click of register check the values entered and register the user
		buttonRegister.setOnClickListener(this);

		// On click of Cancel return the user to the Login screen.
		buttonCancel.setOnClickListener(this);

	}

	/**
	 * The OnClick function of the OnClickListner is implemented here in order
	 * to capture the click on the buttons. This has two major click event
	 * handling 1. Register button. 2. Cancel button.
	 */
	public void onClick(View v) {

		switch (v.getId()) {
		case R.id.buttonRegister:

			String userPassword = RandomPasswordHelper.createRandomPassword();
			String userFullName = fullName.getText().toString();
			String userEmail = emailId.getText().toString();

			Log.d(Constants.LOGGER_REGISTRATION_TAG,
					"Onclick of Register: Email Id: " + userEmail);

			// Check if all the field variables are available to register
			boolean requiredFieldsPresent = ValidationsHelper
					.requiredFieldsPresent(userFullName, userEmail);

			// Pattern foe email syntax matching
			boolean emailMatch = ValidationsHelper.checkEmailFormat(userEmail);

			// Patter matching for Name
			boolean nameMatch = ValidationsHelper.checkNameFormat(userFullName);

			Log.d(Constants.LOGGER_REGISTRATION_TAG,
					"Pre condition values: email match - " + emailMatch
							+ "Required fields Present - "
							+ requiredFieldsPresent);

			// Check if the old and the new passwords are same
			if (emailMatch && requiredFieldsPresent && nameMatch) {
				// Create the database function object
				RegistrationFunctions registrationFunction = new RegistrationFunctions();

				Log.d(Constants.LOGGER_REGISTRATION_TAG,
						"All conditions good, check for uniquness of email id");
				// Get the detail of all the items in the screen and insert it
				// into the database
				String result = registrationFunction
						.checkEmailIdUnique(userEmail);
				result = result.replaceAll("\\s+", "");

				// If the email id is previously registered with the system,
				// then 0 is returned from the database.
				if (result.equals("0")) {
					showDialog(EMAIL_NOT_AVAILABLE);
				} else {
					// If email Id is not found, then it is available for
					// registration.
					// Get the password in the hashed format
					String encryptedPassword = EncryptionHelper
							.encrypt(userPassword);

					// Insert a new record
					registrationFunction.registerUser(userEmail, userFullName,
							encryptedPassword);

					// Get the details of the registered user
					LoginFunctions loginFunctions = new LoginFunctions();
					String response = loginFunctions.userLogin(userEmail,
							encryptedPassword);

					// If the user details are inserted successfully, then send
					// the mail to the user.
					if (response != null) {
						// Send a mail to the user the details of the account
						// with
						// the password.
						try {
							MailHelper mailHelper = new MailHelper();
							String to = userEmail;
							String mailBody = Messages.MAIL_REGISTRATION_MSG;
							mailBody = mailBody.replaceAll(
									Messages.MAIL_LOGIN_EMAIL, userEmail);
							mailBody = mailBody.replaceAll(
									Messages.MAIL_PASSWORD, userPassword);
							String emailSubject = Messages.MAIL_REGISTRATION_SUBJECT;
							mailHelper.sendMail(to, mailBody, emailSubject);
						} catch (Exception e) {
							Log.e(Constants.LOGGER_ERROR_TAG, e.getMessage());
						}
						
						showDialog(SUCCESS_REG);
						
						// Start the new activity
						Intent myIntent = new Intent(RegisterActivity.this,
								LoginActivity.class);
						RegisterActivity.this.startActivity(myIntent);
						finish();
					} else {
						Log.d(Constants.LOGGER_REGISTRATION_TAG,
								"New user not registered, some database error occured.");
						showDialog(UNKNOWN_ERROR);

					}

				}

			} else {
				// This else handles all the negative responses to the users
				// action and displays corresponding messages to the user.
				if (!requiredFieldsPresent) {
					Log.d(Constants.LOGGER_REGISTRATION_TAG,
							"Field blank dialogue");
					showDialog(FIELD_BLANK);
				} else if (!nameMatch) {
					Log.d(Constants.LOGGER_REGISTRATION_TAG,
							"User Name invalid dialogue");
					showDialog(NAME_INVALID);
				} else {
					Log.d(Constants.LOGGER_REGISTRATION_TAG,
							"Email Id not available dialogue");
					showDialog(INVALID_EMAIL);
				}
			}

			break;

		case R.id.buttonCancel:
			// Clear the fields filled by the user. if any
			// Finish the activity
			Intent myIntent = new Intent(RegisterActivity.this,
					LoginActivity.class);
			RegisterActivity.this.startActivity(myIntent);
			RegisterActivity.this.finish();
			break;
		}

	}

	/**
	 * This creates the dialog boxes which display the message to the user.
	 */
	@Override
	protected Dialog onCreateDialog(int id) {

		switch (id) {
		case INVALID_EMAIL:
			// Create out AlterDialog
			Builder builder1 = new AlertDialog.Builder(this);
			builder1.setMessage(Messages.INVALID_EMAIL_HEAD);
			builder1.setMessage(Messages.INVALID_EMAIL_FORMAT);
			builder1.setCancelable(true);
			builder1.setNegativeButton("Dismiss", new CancelOnClickListener());
			AlertDialog dialog1 = builder1.create();
			dialog1.show();
			break;
		case FIELD_BLANK:
			// Create out AlterDialog
			Builder builder2 = new AlertDialog.Builder(this);
			builder2.setMessage(Messages.BLANK_FIELD_HEAD);
			builder2.setMessage(Messages.BLANK_FIELD);
			builder2.setCancelable(true);
			builder2.setNegativeButton("Dismiss", new CancelOnClickListener());
			AlertDialog dialog2 = builder2.create();
			dialog2.show();
			break;
		case EMAIL_NOT_AVAILABLE:
			// Create out AlterDialog
			Builder builder3 = new AlertDialog.Builder(this);
			builder3.setMessage(Messages.EMAIL_UNAVAILABLE_HEAD);
			builder3.setMessage(Messages.EMAIL_UNAVAILABLE);
			builder3.setCancelable(true);
			builder3.setNegativeButton("Dismiss", new CancelOnClickListener());
			AlertDialog dialog3 = builder3.create();
			dialog3.show();
			break;
		case UNKNOWN_ERROR:
			// Create out AlterDialog
			Builder builder4 = new AlertDialog.Builder(this);
			builder4.setMessage(Messages.UNKNOWN_ERROR_HEAD);
			builder4.setMessage(Messages.UNKNOWN_ERROR);
			builder4.setCancelable(true);
			builder4.setNegativeButton("Dismiss", new CancelOnClickListener());
			AlertDialog dialog4 = builder4.create();
			dialog4.show();
			break;
		case NAME_INVALID:
			// Create out AlterDialog
			Builder builder5 = new AlertDialog.Builder(this);
			builder5.setMessage(Messages.NAME_INVALID_HEAD);
			builder5.setMessage(Messages.NAME_INVALID);
			builder5.setCancelable(true);
			builder5.setNegativeButton("Dismiss", new CancelOnClickListener());
			AlertDialog dialog5 = builder5.create();
			dialog5.show();
			break;
		case SUCCESS_REG:
			// Create out AlterDialog
			Builder builder6 = new AlertDialog.Builder(this);
			builder6.setMessage(Messages.SUCCESS_REGISTRATION_HEAD);
			builder6.setMessage(Messages.SUCCESS_REGISTRATION);
			builder6.setCancelable(true);
			builder6.setNegativeButton("Dismiss", new CancelOnClickListener());
			AlertDialog dialog6 = builder6.create();
			dialog6.show();
			break;
			
		}
		return super.onCreateDialog(id);
	}

	/**
	 * Implement the CancelOnClickListner, so that the button can take you to
	 * the Login Page.
	 */
	private final class CancelOnClickListener implements
			DialogInterface.OnClickListener {
		public void onClick(DialogInterface dialog, int which) {
			// Do nothing, as it goes back to login screen
		}
	}

	/**
	 * Override the Back button operation to navigate to the Login page.
	 */
	@Override
	public void onBackPressed() {
		Intent myIntent = new Intent(RegisterActivity.this, LoginActivity.class);
		RegisterActivity.this.startActivity(myIntent);
		finish();
	}

}